package cn.mrcode.fd.blog.services.impl;

import cn.mrcode.fd.blog.cache.CacheConstant;
import cn.mrcode.fd.blog.dao.mapper.TagMapMapper;
import cn.mrcode.fd.blog.dao.mapper.TagMapper;
import cn.mrcode.fd.blog.dao.mappercu.TagCuMapper;
import cn.mrcode.fd.blog.dao.mappercu.TagMapCuMapper;
import cn.mrcode.fd.blog.entity.Tag;
import cn.mrcode.fd.blog.entity.TagMapKey;
import cn.mrcode.fd.blog.services.ITagService;
import cn.mrcode.fd.blog.task.TagCommand;
import cn.mrcode.fd.blog.task.TagHanderTask;
import cn.mrcode.fd.utils.UUID;
import cn.mrcode.fd.utils.collections.SetUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 标签服务
 *
 * @author : zhuqiang
 * @version : V1.0
 * @date : 2015/12/30 22:17
 */
@Service
public class TagServiceImpl implements ITagService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private TagMapMapper tagMapMapper;
    @Autowired
    private TagMapCuMapper tagMapCuMapper;
    @Autowired
    private TagMapper tagMapper;
    @Autowired
    private TagCuMapper tagCuMapper;

    @Override
    public void handerTag(String articleId, String oldTagNames, String newTagNames) {
        Set<String> oldSet = new HashSet<String>();
        if (StringUtils.isNotBlank(oldTagNames)) {
            String[] oldTag = oldTagNames.split(",");
            for (String tagName : oldTag) {
                oldSet.add(tagName);
            }
        }
        Set<String> newSet = new HashSet<String>();
        if (StringUtils.isNotBlank(newTagNames)) {
            String[] newTag = newTagNames.split(",");
            for (String tagName : newTag) {
                newSet.add(tagName);
            }
        }
        //删除该标签对文章的引用
        Set<String> delSet = SetUtils.difference(oldSet, newSet);
        //新增这些标签对文章的引用，有可能这些标签并不存在
        Set<String> addSet = SetUtils.newSet(oldSet, newSet);

        for (String tagName : delSet) {
            TagHanderTask.deque.add(new TagCommand(2,articleId,tagName));
        }
        for (String tagName : addSet) {
            TagHanderTask.deque.add(new TagCommand(1,articleId,tagName));
        }
    }

    @Override
    @Transactional
    public void delRefNum(TagCommand tagCommand) {
        Tag tag = tagMapper.selectByPrimaryKey(tagCommand.getTagId());
        if(tag == null){
            return;
        }
        //减少索引
        tag.setNum(tag.getNum()-1);
        tagMapper.updateByPrimaryKeySelective(tag);
        //更新缓存
        CacheConstant.TAG_MAP.put(tag.getName(),tag);
    }

    @Override
    @Transactional
    public void addRef(TagCommand tagCommand) {
        String tagName = tagCommand.getTagName();
        Tag tag = CacheConstant.TAG_MAP.get(tagName);
        if(tag == null){ //标签不存在，新增
            tag = new Tag();
            tag.setId(UUID.uuid());
            tag.setName(tagName);
            tag.setNum(1);
            tagMapper.insert(tag);
            CacheConstant.TAG_MAP.put(tagName,tag);
        }else{ //存在则把索引加1
            tag.setNum(tag.getNum()+1);
            tagMapper.updateByPrimaryKeySelective(tag);
        }

        //再添加引用
        TagMapKey tagMapKey = new TagMapKey();
        tagMapKey.setTagId(tag.getId());
        tagMapKey.setArticleId(tagCommand.getArticleId());
        tagMapMapper.insert(tagMapKey);
    }

    @Override
    @Transactional
    public void delRef(String articleId) {
        TagMapKey tagMapKey = new TagMapKey();
        tagMapKey.setArticleId(articleId);
        List<TagMapKey> tagMapKeys = tagMapCuMapper.selectSelective(tagMapKey);
        if(CollectionUtils.isEmpty(tagMapKeys)){
            return;
        }

        for (TagMapKey mapKey : tagMapKeys) {
            TagCommand tagCommand = new TagCommand(TagCommand.OPER_TYPE_del, mapKey.getTagId());
            tagMapMapper.deleteByPrimaryKey(mapKey);
            TagHanderTask.deque.add(tagCommand);
        }
    }

    @Autowired
    public List<Tag> findAll(){
        List<Tag> tags = tagCuMapper.selectSelective(null);
        return tags;
    }
}
